package org.management.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.management.base.data.PermissionCode;
import org.management.base.data.Result;
import org.management.base.data.ResultCode;
import org.management.page.Pagination;
import org.management.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import javax.validation.constraints.NotEmpty;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map.Entry;

/**
 * @title: BaseController
 * @description: 公用增删改查
 * @author: jiangyan
 * @date:  2019/1/27
 */
public abstract class BaseController<E extends BaseEntity> {

	private Class<T> entityClass;

	@Autowired
	private BaseService<E> baseService;

	@SuppressWarnings("unchecked")
    public BaseController(){
		Type type = getClass().getGenericSuperclass();
		Type trueType = ((ParameterizedType) type).getActualTypeArguments()[0];
		if (trueType instanceof  Class){
			this.entityClass = (Class<T>) trueType;
		}
	}

	/**
	 * 根据条件查询数据
	 * @param page 分页参数
	 * @param entity 条件查询
	 * @return Pagination 分页及数据信息
	 */
	@GetMapping
	@RequiresPermissions(value = PermissionCode.USER_READ_LIST)
	public Result getEntities(Pagination<E> page, E entity) {
		Example example = new Example(entityClass);
		Criteria criteria = example.createCriteria();
		JSONObject object = (JSONObject) JSON.toJSON(entity);
		String order = page.getOrder();
		Integer pageNum = page.getPageNum();
		Integer pageSize = page.getPageSize();
		if (!object.isEmpty()) {
			getCriteriaParam(object, criteria);
		}
		if (StringUtils.isNotBlank(order)) {
			String sort = page.getSort();
			if (StringUtils.isEmpty(sort)) {
				example.orderBy(order);
			} else {
				example.setOrderByClause(humpToUnderline(order, sort));
			}
		}
		if (pageNum != 0 && pageSize != 0){
			PageHelper.startPage(pageNum, pageSize);
			List<E> rows = this.baseService.selectByExample(example);
			return Result.success("获取信息成功",new Pagination<>(rows));
		} else {
			List<E> rows = this.baseService.selectByExample(example);
			return Result.success("获取信息成功",rows);
		}
	}

	/**
	 * 根据id获取权限数据
	 * @param id 实体id
	 * @return 实体对象
	 */
	@GetMapping(value = "/{id}")
	@RequiresPermissions(value = PermissionCode.USER_READ_GET)
	public Result getEntityById(@PathVariable @NotEmpty(message = "id不能为空") String id) {
		E entity = this.baseService.selectByKey(id);
		return Result.success("获取数据成功",entity);
	}

	/**
	 * 保存权限信息
	 * @param entity 实体对象
	 */
	@PostMapping
	@RequiresPermissions(value = PermissionCode.USER_WRITE_EDIT)
	public Result saveEntity(@Validated E entity) {
		this.baseService.save(entity);
		return Result.success(ResultCode.CREATED.getCode(),"保存成功");
	}

	/**
	 * 修改权限信息
	 * @param entity 实体对象
	 */
	@PutMapping
	@RequiresPermissions(value = PermissionCode.USER_WRITE_EDIT)
	public Result updateEntity(@Validated E entity) {
		this.baseService.updateNotNull(entity);
		return Result.success("修改成功");
	}

	/**
	 * 删除权限信息
	 * @param id 实体id
	 * @return ResultData 数据结果集
	 */
	@DeleteMapping(value = "/{id}")
	@RequiresPermissions(value = PermissionCode.USER_WRITE_DEL)
	public Result delete(@PathVariable @NotEmpty(message = "id不能为空") String id) {
		this.baseService.delete(id);
		return Result.success("删除成功");
	}

	/**
	 * 参数jsonObject 查询条件拼接
	 * @param object json键值对
	 * @param criteria 通用mapper 查询对象
	 */
	private void getCriteriaParam (JSONObject object, Criteria criteria) {
		for (Entry<String, Object> entry : object.entrySet()) {
			Object value = entry.getValue();
			if (StringUtils.isNotEmpty(value)) {
				if (value instanceof Boolean) {
					value = (boolean) value?1:0;
					criteria.andEqualTo(entry.getKey(), value);
				} else {
					criteria.andLike(entry.getKey(), value + "%");
				}
			}
		}
	}

    /***
     * @description  驼峰命名转为下划线命名
     * @param sort 排序
     * @param param 参数
     */
    private String humpToUnderline(String param, String sort){
        StringBuilder sb = new StringBuilder(param);
        int temp = 0;
        for (int i = 0;i < param.length(); i++) {
            if (Character.isUpperCase(param.charAt(i))) {
                sb.insert(i+temp, "_");
                temp += 1;
            }
        }
        sb.append(" ").append(sort);
        return sb.toString();
    }
}
